import React, { useEffect, useState } from 'react';
import {
  Space,
  Card,
  Form,
  Avatar,
  Checkbox,
  DatePicker,
  Image,
  Input,
  Select,
  Button,
  Table,
  Modal,
  Spin,
  Tabs,
  Tooltip,
  message
} from 'antd';
import {
  ExclamationCircleFilled,
  InfoCircleOutlined,
  UserOutlined
} from '@ant-design/icons';
import type { TabsProps } from 'antd';
import columns from '../../components/columns/userColumns';
import hasAuthority from '../../components/hasAuthority';
import { useStore, observer } from '../../store/user/storeHook';
import * as patterns from '../../data/patterns';
import userImageData from '../../data/userImageData';
import { booleanOptions, userTypes } from '../../data/statusData';
import { trimObject } from '../../utils/dataUtils';

const { TextArea } = Input;

const UserManagement: React.FC = () => {
  const [searchForm] = Form.useForm();
  const [editForm] = Form.useForm();
  const [messageApi, contextHolder] = message.useMessage();
  const [modal, modalContextHolder] = Modal.useModal();

  const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
  const [activeKey, setActiveKey] = useState<string>('1');

  const store: any = useStore();

  const rowSelection = {
    onChange: (selectedRowKeys: React.Key[], selectedRows: any[]) => {
      store.user.selectRecord(selectedRows[0]);
    },
    getCheckboxProps: (record: any) => ({
      name: record.id
    })
  };

  const pagination = {
    showSizeChanger: true,
    showQuickJumper: true,
    pageSizeOptions: [10, 20, 30, 40, 50, 100],
    current: store.user.current + 1,
    pageSize: store.user.pageSize,
    total: store.user.total,
    onChange: (page: number, pageSize: number) => {
      store.user.setPageSize(pageSize);
      search(page - 1);
    },
    onShowSizeChange: (current: number, size: number) => {
      store.user.setPageSize(size);
      search(current - 1);
    }
  };

  const tabItems: TabsProps['items'] = [
    {
      key: '1',
      label: '用户信息',
      forceRender: true,
      children: <>
        <Form.Item
          name="name"
          label="姓名"
        >
          <Input maxLength={32} />
        </Form.Item>
        <Form.Item
          name="company"
          label="公司"
        >
          <Input maxLength={32} />
        </Form.Item>
        <Form.Item
          name="department"
          label="部门"
        >
          <Input maxLength={32} />
        </Form.Item>
        <Form.Item
          name="title"
          label="职位"
        >
          <Input maxLength={32} />
        </Form.Item>
        <Form.Item
          name="email"
          label="Email"
          rules={[
            { pattern: patterns.emailPattern, message: 'Email格式不正确' }
          ]}
        >
          <Input maxLength={64} />
        </Form.Item>
        <Form.Item
          name="mobile"
          label="手机"
          rules={[
            { required: true, message: '手机不能为空' },
            { pattern: patterns.mobilePattern, message: '手机格式不正确' }
          ]}
          tooltip={{ title: '11位数字手机号', icon: <InfoCircleOutlined /> }}
        >
          <Input maxLength={16} />
        </Form.Item>
        <Form.Item
            name="telephone"
            label="电话"
            rules={[
              { pattern: patterns.phonePattern, message: '电话格式不正确' }
            ]}
            tooltip={{ title: '格式：(2-3位区号)-(7-8位电话号码)-(1-4位分机号，可无分机号)', icon: <InfoCircleOutlined /> }}
          >
          <Input maxLength={32} />
        </Form.Item>
        <Form.Item
          name="remark"
          label="备注"
        >
          <TextArea
            maxLength={256}
            rows={3}
          />
        </Form.Item>
      </>
    },
    {
      key: '2',
      label: '账号相关',
      forceRender: true,
      children: <>
        <Form.Item
          name="username"
          label="用户名"
          rules={[
            { required: true, message: '用户名不能为空' },
            { pattern: patterns.usernamePattern, message: '用户名不符合规则' }
          ]}
          tooltip={{ title: '用户名必须由英文字母/数字/下划线（_）/连字符（-）组成，2-16位，且以英文字母开头，不能以下划线或连字符结尾', icon: <InfoCircleOutlined /> }}
          className={store.user.record ? 'readonly' : ''}
        >
          <Input
            maxLength={32}
            readOnly={store.user.record ? true : false}
          />
        </Form.Item>
        <Form.Item
          name="newPassword"
          label="密码"
          rules={
            store.user.passwordStatus === 'unset' ?
              [] :
              [
                { required: true, message: '密码不能为空' },
                { pattern: patterns.passwordPattern, message: '密码不符合规则' }
              ]
          }
          tooltip={store.user.passwordStatus === 'unset'? null : { title: '密码长度为6-16位，必须包含数字，且必须包含字母或其它字符（!@_#$%^&*()-+=,.?）', icon: <InfoCircleOutlined /> }}
          className={store.user.passwordStatus === 'unset' ? 'readonly' : ''}
        >
          <Input.Password
            addonBefore={
              store.user.passwordStatus === 'required' ?
                null :
                <Form.Item
                  name="passwordChanged"
                  valuePropName="checked"
                  noStyle
                >
                  <Checkbox onChange={e => store.user.setPasswordStatus(e.target.checked ? 'changed' : 'unset', editForm)} />
                </Form.Item>
            }
            maxLength={16}
            readOnly={store.user.passwordStatus === 'unset'}
          />
        </Form.Item>
        <Form.Item
          name="active"
          valuePropName="checked"
          wrapperCol={{ sm: { offset: 6, span: 16 }, xs: { span: 24 } }}
        >
          <Checkbox>可用</Checkbox>
        </Form.Item>
        <Form.Item
          name="locked"
          valuePropName="checked"
          wrapperCol={{ sm: { offset: 6, span: 16 }, xs: { span: 24 } }}
        >
          <Checkbox>锁定</Checkbox>
        </Form.Item>
        <Form.Item
          name="superuser"
          valuePropName="checked"
          wrapperCol={{ sm: { offset: 6, span: 16 }, xs: { span: 24 } }}
        >
          <Checkbox>管理员</Checkbox>
        </Form.Item>
        <div className="form-group">
          <Form.Item
            name="type"
            label="类型"
            rules={[{ required: true, message: '类型不能为空' }]}
          >
            <Select options={userTypes} />
          </Form.Item>
          <Form.Item
            name="authorizedOpinions"
            label="审核意见"
            tooltip={{ title: '对于非管理员用户，如果选择类型为“未授权用户”，建议填入审核意见，让用户看到为什么未被授权', icon: <InfoCircleOutlined /> }}
          >
            <TextArea
              maxLength={256}
              rows={3}
            />
          </Form.Item>
        </div>
        <Form.Item
          name="effectiveDateValue"
          label="账号生效日期"
        >
          <DatePicker
            format="YYYY-MM-DD"
            showTime={false}
            style={{ width: '100%' }}
          />
        </Form.Item>
        <Form.Item
          name="terminateDateValue"
          label="账号过期日期"
        >
          <DatePicker
            format="YYYY-MM-DD"
            showTime={false}
            style={{ width: '100%' }}
          />
        </Form.Item>
        <Form.Item
          name="passwordTerminateDateValue"
          label="密码过期日期"
        >
          <DatePicker
            format="YYYY-MM-DD"
            showTime={false}
            style={{ width: '100%' }}
          />
        </Form.Item>
        <Form.Item
          name="needChangePassword"
          valuePropName="checked"
          wrapperCol={{ sm: { offset: 6, span: 16 }, xs: { span: 24 } }}
        >
          <Checkbox>
            <Space className="with-tooltip-icon">
              需要更改密码
              <Tooltip title="用户下次登录时需要更改密码">
                <InfoCircleOutlined />
              </Tooltip>
            </Space>
          </Checkbox>
        </Form.Item>
        <Form.Item
          name="lastLoginTime"
          label="最后登录时间"
          className="readonly"
        >
          <Input readOnly />
        </Form.Item>
        <Form.Item
          name="lastLoginIp"
          label="最后登录IP"
          className="readonly"
        >
          <Input readOnly />
        </Form.Item>
        <Form.Item
          name="failedLoginAttempts"
          label="密码重试次数"
          className="readonly"
        >
          <Input readOnly />
        </Form.Item>
      </>
    },
    {
      key: '3',
      label: '头像',
      forceRender: true,
      children: store.user.record?.avatar ?
        <Avatar
          draggable={false}
          shape="square"
          size={256}
          src={
            <Image
              src={store.user.record?.avatar.startsWith('/') ? store.user.record?.avatar : ('/' + store.user.record?.avatar)}
              fallback={userImageData}
              preview={false}
            />
          }
          style={{ backgroundColor: '#ffffff' }}
        /> :
        <Avatar
          draggable={false}
          shape="square"
          size={256}
          icon={<UserOutlined style={{ color: '#707070', fontSize: 228 }} />}
          style={{ backgroundColor: '#ffffff' }}
        />
    }
  ];

  const search = (pageNumber: number) => {
    const values = getSearchValues();
    store.user.fetchData(values.keyword, values.active, values.locked, values.superuser, values.type, pageNumber);
  };

  const getSearchValues = () => {
    const values: any = searchForm.getFieldsValue(true);
    values.keyword = (values.keyword as string || '').trim();
    return values;
  };

  const editRecord = (record?: any) => {
    store.user.selectRecord(record);
    store.user.setPasswordStatus(record ? 'unset' : 'required');
    if (record?.id) {
      store.user.fetchDetail();
    }
    setIsModalOpen(true);
    editForm.resetFields();
    editForm.setFieldsValue(store.user.getEditRecord());
  };

  const deleteRecord = () => {
    if (!store.user.record) {
      messageApi.info('请选择要删除的记录');
      return;
    }
    modal.confirm({
      title: '确定删除当前选中的记录吗？',
      icon: <ExclamationCircleFilled />,
      onOk() {
        store.user.deleteData().then((res: any) => {
          if (res.success) {
            messageApi.info('删除成功');
            search(store.user.current);
          } else {
            messageApi.error(res.message);
          }
        });
      },
      onCancel() {}
    });
  };

  const saveRecord = (values: any) => {
    if (store.user.saving) {
      return;
    }
    editForm.setFieldsValue(trimObject(values));
    store.user.saveData(values).then((res: any) => {
      store.user.setSaving(false);
      if (res.success) {
        setIsModalOpen(false);
        messageApi.info('保存成功');
        if (store.user.record) {
          search(store.user.current);
          if (store.user.record.username === store.currentUser.userData.username) {
            store.currentUser.fetch();
          }
        } else {
          store.user.addRecord(res.data);
        }
      } else {
        messageApi.error(res.message);
      }
    });
  };

  useEffect(() => {
    const values = store.user.conditions;
    store.user.fetchData(values.keyword, values.active, values.locked, values.superuser, values.type, values.pageNumber);
  }, []); // eslint-disable-line react-hooks/exhaustive-deps

  const forbiddenComponent: React.ReactNode = hasAuthority(store, 'admin');
  if (forbiddenComponent) {
    return forbiddenComponent;
  }

  return (
    <>
      {contextHolder}
      {modalContextHolder}
      <Space
        direction="vertical"
        size={[0, 16]}
        style={{ width: '100%', padding: 16 }}
      >
        <Card
          size="small"
          title={
            <Space style={{ paddingTop: 8, paddingBottom: 16 }}>
              <Space.Compact block>
                <Button
                  disabled={store.user.loading}
                  type="primary"
                  htmlType="button"
                  onClick={() => search(0)}
                >
                  查询
                </Button>
                <Button
                  disabled={store.user.loading}
                  htmlType="button"
                  onClick={() => store.user.resetConditions(searchForm)}
                >
                  重置
                </Button>
              </Space.Compact>
              <Space.Compact block>
                <Button
                  disabled={store.user.loading}
                  type="primary"
                  htmlType="button"
                  onClick={() => editRecord(null)}
                >
                  新增
                </Button>
                <Button
                  disabled={store.user.loading}
                  type="primary"
                  htmlType="button"
                  danger
                  onClick={deleteRecord}
                >
                  删除
                </Button>
              </Space.Compact>
            </Space>
          }
          style={{ paddingTop: 12 }}
        >
          <Form
            form={searchForm}
            name="searchForm"
            autoComplete="off"
            colon={false}
            layout="inline"
            disabled={store.user.loading}
            initialValues={store.user.conditions}
            className="search-form"
          >
            <Form.Item
              name="keyword"
              label="关键词"
            >
              <Input
                autoFocus
                maxLength={128}
                placeholder="用户名/姓名/公司/职位/Email/手机/电话"
                style={{ width: 280 }}
              />
            </Form.Item>
            <Form.Item
              name="active"
              label="可用"
            >
              <Select
                options={booleanOptions}
                style={{ width: 80 }}
              />
            </Form.Item>
            <Form.Item
              name="locked"
              label="锁定"
            >
              <Select
                options={booleanOptions}
                style={{ width: 80 }}
              />
            </Form.Item>
            <Form.Item
              name="superuser"
              label="管理员"
            >
              <Select
                options={booleanOptions}
                style={{ width: 80 }}
              />
            </Form.Item>
            <Form.Item
              name="type"
              label="类型"
            >
              <Select
                options={userTypes}
                style={{ width: 120 }}
              />
            </Form.Item>
          </Form>
        </Card>
        <Table
          columns={columns(booleanOptions, userTypes, editRecord)}
          dataSource={store.user.data}
          rowKey="id"
          loading={store.user.loading}
          bordered
          scroll={{ x: 'max-content' }}
          rowSelection={{
            type: 'radio',
            selectedRowKeys: store.user.record ? [store.user.record.id] : [],
            ...rowSelection
          }}
          pagination={pagination}
        />

        <Modal
          title="用户"
          open={isModalOpen}
          okText="确定"
          cancelText="取消"
          maskClosable={false}
          destroyOnHidden
          forceRender
          closable={!store.user.saving}
          confirmLoading={store.user.saving}
          style={{ minWidth: 320 }}
          onOk={() => editForm.submit()}
          onCancel={() => {
            if (!store.user.saving) setIsModalOpen(false)
          }}
          footer={(_, { OkBtn, CancelBtn }) => (
            <><OkBtn /><CancelBtn /></>
          )}
        >
          <Spin spinning={store.user.detailLoading || store.user.saving}>
            <Form
              form={editForm}
              name="editForm"
              autoComplete="off"
              disabled={store.user.saving}
              labelCol={{ span: 6 }}
              wrapperCol={{ span: 16 }}
              preserve={false}
              onFinish={saveRecord}
              onFinishFailed={() => messageApi.warning('数据校验错误')}
            >
              <Tabs
                activeKey={activeKey}
                items={tabItems}
                onChange={key => setActiveKey(key)}
              />
            </Form>
          </Spin>
        </Modal>
      </Space>
    </>
  );
};

export default observer(UserManagement);
